﻿namespace TspDemo.CSharp
{
   using System;
   using System.Collections.Generic;
   using System.Linq;
   using ClearLines.Bumblebee;
   using Random = System.Random;

   class Program
   {
      static void Main(string[] args)
      {
         var radius = 10d;
         var count = 26;

         var cities = new List<City>();
         var angle = Math.PI * 2.0 / (double)count;
         for (var i = 0; i < count; i++)
         {
            var x = Math.Cos(angle * (double)i) * radius;
            var y = Math.Sin(angle * (double)i) * radius;
            var city = new City(i.ToString(), x, y);
            cities.Add(city);
         }

         var rng = new Random();
         cities = new List<City>(Tsp.Shuffle(rng, cities));

         var generator = new Func<Random, IList<City>>((random) =>
            Tsp.Shuffle(random, cities));

         var mutator = new Func<Tuple<Random, IList<City>>, IList<City>>((tuple) =>
            Tsp.Swap(tuple.Item1, tuple.Item2));

         var evaluator = new Func<IList<City>, double>((circuit) =>
            -Tsp.Length(circuit));

         var problem = new Problem<IList<City>>(generator, mutator, evaluator);

         var solver = new Solver<IList<City>>();
         solver.FoundSolution += SolutionFound;

         Console.WriteLine("Starting!");
         solver.Search(problem);

         Console.ReadLine();
         Console.WriteLine("Stopped!");
         solver.Stop();

         Console.ReadLine();
         Console.WriteLine("Closed!");
      }

      static void SolutionFound(object sender, SolutionMessage<IList<City>> args)
      {
         Console.WriteLine("{0:F2}, {1}", args.Quality, args.DateTime.TimeOfDay);
         var cities = args.Solution.Select(it => it.Name);
         Console.WriteLine(string.Join(",", cities.ToArray()));
      }
   }
}
